//
// Created by madison on 2022/1/6.
//

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int main() {
    int var_runoob = 10;
    int *p;              // 定义指针变量
    p = &var_runoob;

    printf("var_runoob 变量的地址： %p\n", p);

    int var = 20;   /* 实际变量的声明 */
    int *ip;        /* 指针变量的声明 */

    ip = &var;  /* 在指针变量中存储 var 的地址 */

    printf("var 变量的地址: %p\n", &var);

    /* 在指针变量中存储的地址 */
    printf("ip 变量存储的地址: %p\n", ip);

    /* 使用指针访问值 */
    printf("*ip 变量的值: %d\n", *ip);

    int *ptr = NULL;

    printf("ptr 的地址是 %p\n", ptr);

    void fun();
    fun();
    void fun1();
    fun1();
    void fun2();
    fun2();
    void fun3();
    fun3();
    void fun4();
    fun4();
    return 0;
}

const int MAX = 3;

void fun() {
    int var[] = {10, 100, 200};
    int i, *ptr;

    /* 指针中的数组地址 */
    ptr = var;
    for (i = 0; i < MAX; i++) {

        printf("存储地址：var[%d] = %p\n", i, ptr);
        printf("存储值：var[%d] = %d\n", i, *ptr);

        /* 指向下一个位置 */
        ptr++;
    }
}

void fun1() {
    int var[] = {10, 100, 200};
    int i, *ptr;

    /* 指针中最后一个元素的地址 */
    ptr = &var[MAX - 1];
    for (i = MAX; i > 0; i--) {

        printf("存储地址：var[%d] = %p\n", i - 1, ptr);
        printf("存储值：var[%d] = %d\n", i - 1, *ptr);

        /* 指向下一个位置 */
        ptr--;
    }
}

void fun2() {
    int var[] = {10, 100, 200};
    int i, *ptr;

    /* 指针中第一个元素的地址 */
    ptr = var;
    i = 0;
    while (ptr <= &var[MAX - 1]) {
        printf("存储地址：var[%d] = %p\n", i, ptr);
        printf("存储值：var[%d] = %d\n", i, *ptr);

        /* 指向上一个位置 */
        ptr++;
        i++;
    }
}

// 指针数组
void fun3() {
    int var[] = {10, 100, 200};
    int i, *ptr[MAX];

    for (i = 0; i < MAX; i++) {
        ptr[i] = &var[i]; /* 赋值为整数的地址 */
    }
    for (i = 0; i < MAX; i++) {
        printf("Value of var[%d] = %d\n", i, *ptr[i]);
    }
}

void fun4() {
    const char *names[] = {
            "Zara Ali",
            "Hina Ali",
            "Nuha Ali",
            "Sara Ali",
    };
    int i = 0;

    for (i = 0; i < MAX; i++) {
        printf("Value of names[%d] = %s\n", i, names[i]);
    }
}

// 指向指针的指针（多级间接寻址）
void fun5() {
    int V;
    int *Pt1;
    int **Pt2;

    V = 100;

    /* 获取 V 的地址 */
    Pt1 = &V;

    /* 使用运算符 & 获取 Pt1 的地址 */
    Pt2 = &Pt1;

    /* 使用 pptr 获取值 */
    printf("var = %d\n", V);
    printf("Pt1 = %p\n", Pt1);
    printf("*Pt1 = %d\n", *Pt1);
    printf("Pt2 = %p\n", Pt2);
    printf("**Pt2 = %d\n", **Pt2);
}

//传递指针给函数

void getSeconds(unsigned long *par);

void fun6() {
    unsigned long sec;
    getSeconds(&sec);

    /* 输出实际值 */
    printf("Number of seconds: %ld\n", sec);
}

void getSeconds(unsigned long *par) {
    /* 获取当前的秒数 */
    *par = time(NULL);
    return;
}

/* 函数声明 */
double getAverage(int *arr, int size);

void fun7() {
    /* 带有 5 个元素的整型数组  */
    int balance[5] = {1000, 2, 3, 17, 50};
    double avg;

    /* 传递一个指向数组的指针作为参数 */
    avg = getAverage(balance, 5);

    /* 输出返回值  */
    printf("Average value is: %f\n", avg);
}

double getAverage(int *arr, int size) {
    int i, sum = 0;
    double avg;

    for (i = 0; i < size; ++i) {
        sum += arr[i];
    }

    avg = (double) sum / size;

    return avg;
}

//从函数返回指针
/* 要生成和返回随机数的函数 */
int *getRandom() {
    static int r[10];

    /* 设置种子 */
    srand((unsigned) time(NULL));
    for (int i = 0; i < 10; ++i) {
        r[i] = rand();
        printf("%d\n", r[i]);
    }

    return r;
}

void fun8() {
    /* 一个指向整数的指针 */
    int *p;

    p = getRandom();
    for (int i = 0; i < 10; i++) {
        printf("*(p + [%d]) : %d\n", i, *(p + i));
    }

}